package com.rabbitmq.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * 交换机四种：
 *      直连交换机
 *      扇形交换机
 *      主题交换机
 *      头交换机 一般用不上，此项目没有
 */
@Configuration
public class RabbitmqConfig {

    /** ********************************************* 直连交换机  ****************************************************** **/

    /**
     * 消息队列
     * 参考文档：
     *      https://blog.csdn.net/weixin_44301905/article/details/123871172
     * @return
     */
    @Bean
    public Queue smsDirectQueue() {
        Map<String, Object> arguments = new HashMap<>();
        // 声明当前死信队列绑定的死信交换机,可以是任何类型的交换机
        arguments.put("x-dead-letter-exchange", "huawei_dead_letter_from_sms_exchange");
        // 声明当前队列的死信路由键
        arguments.put("x-dead-letter-routing-key", "dead_letter_from_sms_key");
        // 设置队列消息的超时时间，单位毫秒，超过时间进入死信队列,也可以在发送消息处设置超时时间，都设置时，以最小超时时间为准
//        arguments.put("x-message-ttl",3000);
        // 生命队列的最大长度，超过长度的消息进入死信队列
//        arguments.put("x-max-length", 10);
        return new Queue("sms_direct_queue", true, false, false, arguments);
    }

    /**
     * 消息队列的死信队列
     *
     * @return
     */
    @Bean
    public Queue deadLetterFromSmsQueue() {
        return new Queue("dead_letter_queue_from_sms_queue");
    }

    /**
     * sms直连交换机
     *
     * @return
     */
    @Bean
    public DirectExchange directSmsExchange() {
        return new DirectExchange("huawei_direct_sms_exchange");
    }

    /**
     * sms直连死信队列交换机
     *
     * @return
     */
    @Bean
    public DirectExchange deadDirectFromSmsExchange() {
        return new DirectExchange("huawei_dead_letter_from_sms_exchange");
    }

    /**
     * 消息队列和直连交换机进行绑定
     *
     * @return
     */
    @Bean
    public Binding smsDirectBinding() {
        return BindingBuilder.bind(smsDirectQueue()).to(directSmsExchange()).with("sms_direct_key");
    }

    /**
     * 死信队列和直连交换机进行绑定
     *
     * @return
     */
    @Bean
    public Binding deadDirectSmsBinding() {
        return BindingBuilder.bind(deadLetterFromSmsQueue()).to(deadDirectFromSmsExchange()).with("dead_letter_from_sms_key");
    }

    /** ********************************************* 扇形交换机  ****************************************************** **/

    /**
     * 扇形sms队列
     *
     * @return
     */
    @Bean
    public Queue fanoutSmsQueue() {
        return new Queue("fanout_sms_queue");
    }

    /**
     * 扇形email队列
     *
     * @return
     */
    @Bean
    public Queue fanoutEmailQueue() {
        return new Queue("fanout_email_queue");
    }

    /**
     * 扇形交换机
     *
     * @return
     */
    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange("huawei_fanout_exchange");
    }

    /**
     * sms队列和扇形交换机进行绑定
     *
     * @return
     */
    @Bean
    public Binding smsFanoutBinding() {
        return BindingBuilder.bind(fanoutSmsQueue()).to(fanoutExchange());
    }

    /**
     * 邮件队列和扇形交换机进行绑定
     *
     * @return
     */
    @Bean
    public Binding emailFanoutBinding() {
        return BindingBuilder.bind(fanoutEmailQueue()).to(fanoutExchange());
    }

    /** ********************************************* 直连交换机  ****************************************************** **/


    /**
     * 主题sms队列
     *
     * @return
     */
    @Bean
    public Queue topicSmsQueue() {
        return new Queue("topic_sms_queue");
    }

    /**
     * 主题sms队列(模糊匹配队列)
     *
     * @return
     */
    @Bean
    public Queue topicSmsBigQueue() {
        return new Queue("topic_sms_big_queue");
    }

    /**
     * 主题email队列
     *
     * @return
     */
    @Bean
    public Queue topicEmailQueue() {
        return new Queue("topic_email_queue");
    }

    /**
     * 主题email队列(模糊匹配队列)
     *
     * @return
     */
    @Bean
    public Queue topicEmailBigQueue() {
        return new Queue("topic_email_big_queue");
    }

    /**
     * 主题交换机
     *
     * @return
     */
    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange("huawei_topic_exchange");
    }

    /**
     * sms队列和主题交换机进行绑定
     * 注意：
     *      #： 代表匹配多个单词，比如(email.key, email.topic.key.routing, email.routing.key)
     *      *:  代表匹配一个的单词，比如(email.key, email.routing, email.topic)
     * @return
     */
    @Bean
    public Binding smsTopicBinding() {
        return BindingBuilder.bind(topicSmsQueue()).to(topicExchange()).with("sms.topic.*");
    }

    /**
     * email队列和主题交换机进行绑定
     *
     * 注意：
     *      #： 代表匹配多个单词，比如(email.key, email.topic.key.routing, email.routing.key)
     *      *:  代表匹配一个的单词，比如(email.key, email.routing, email.topic)
     * @return
     */
    @Bean
    public Binding emailTopicBinding() {
        return BindingBuilder.bind(topicEmailQueue()).to(topicExchange()).with("email.topic.*");
    }

    /**
     * sms队列和主题交换机进行绑定(模糊匹配队列)
     * 注意：
     *      #： 代表匹配多个单词，比如(email.key, email.topic.key.routing, email.routing.key)
     *      *:  代表匹配一个的单词，比如(email.key, email.routing, email.topic)
     *
     * @return
     */
    @Bean
    public Binding smsTopicBigBinding() {
        return BindingBuilder.bind(topicSmsBigQueue()).to(topicExchange()).with("sms.#");
    }

    /**
     * email队列和主题交换机进行绑定(模糊匹配队列)
     *
     * 注意：
     *      #： 代表匹配多个单词，比如(email.key, email.topic.key.routing, email.routing.key)
     *      *:  代表匹配一个的单词，比如(email.key, email.routing, email.topic)
     *
     * @return
     */
    @Bean
    public Binding emailTopicBigBinding() {
        return BindingBuilder.bind(topicEmailBigQueue()).to(topicExchange()).with("email.#");
    }


}
